#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

typedef int ElemType;
typedef struct {
    ElemType *elem;
    int TableLen;
}SSTable;
//初始化顺序表
void ST_Init(SSTable &ST,int len)
{
    ST.TableLen=len;
    ST.elem=(ElemType*)malloc(sizeof(ElemType) * ST.TableLen);
    srand(time(NULL));  //随机生成数
    for (int j = 0; j < ST.TableLen; j++)
    {
        ST.elem[j]=rand() % 100; //为了随机生成的书都在0-99之间
    }
}
void ST_Print(SSTable ST)
{
    for (int i = 0; i < ST.TableLen; ++i) {
        printf("%3d",ST.elem[i]);
    }
    printf("\n");
}
void swap(int &a,int &b)
{
    int temp;
    temp=a;
    a=b;
    b=temp;
}
//把某个子树调整为大根堆
void AdjustDown(ElemType *A,int k,int len)
{
    int dad=k;  //父亲的下标
    int son=2*dad+1; //左孩子下标
    while (son<len)  //孩子结点下标不超过长度
    {
        if(son+1<len&&A[son]<A[son+1]) //如果左孩子小于右孩子,而且要判断存在右孩子
        {
            son++; //拿右孩子
        }
        if(A[son]>A[dad]) //如果孩子大于父亲
        {
            swap(A[son],A[dad]); //交换元素
            dad=son;  //孩子作为新的dad,取判断下面的子树是否符合大根堆
            son=2*dad+1;
        } else{
            break;
        }
    }
}
void HeapSort(ElemType *A,int len)
{
    int i,j;
    //把堆调整为大根堆
    for (i=len/2-1;i>=0;i--)   //len/2-1 最后一个子树的父节点
    {
        AdjustDown(A,i,len);
    }
    swap(A[0],A[len-1]); //交换根元素和最后一个元素
    for (j=len-1;j>1;j--)      //j代表的是剩余无序数的数组的长度
    {
        AdjustDown(A,0,j);    //调整剩余元素为大根堆
        swap(A[0],A[j-1]); //交换根元素和无序数的数组最后一个元素
    }
}
int main() {
    SSTable ST;
    ST_Init(ST,10);
//    ElemType A[10]={3,87,2,93,78,56,61,38,12,40};
//    //内存copy接口，当你copy整型数组，或者浮点型时，使用memcpy，不能用strcpy，初试考memcpy概率很低
//    memcpy(ST.elem,A,sizeof(A)); //这是为了降低调试难度，每次数组数据固定而设计
    ST_Print(ST);
    HeapSort(ST.elem,10);
    ST_Print(ST);
    return 0;
}
